#ifndef __TCPSERVER_H__
#define __TCPSERVER_H__

#include "eventloop.h"
#include "Base/callback.h"
#include "acceptor.h"
#include "eventloopthreadpool.h"
#include <functional>
#include <memory>
#include <unordered_map>
#include "Base/noncopyable.h"

namespace tiny_muduo
{
    class Address;
    class EventLoopThreadPool;
    
    class TcpServer : public NonCopyable
    {
    public:
        TcpServer(EventLoop* loop, const Address& address);
        ~TcpServer();

        void Start()
        {
            threadpool_->StartLoop();
            loop_->RunOneFunc(std::bind(&Acceptor::Listen, acceptor_.get()));
        }

        void SetConnectionCallback(ConnectionCallback&& callback)
        {
            connection_callback_ = std::move(callback);
        }

        void SetConnectionCallback(const ConnectionCallback& callback)
        {
            connection_callback_ = callback;
        }

        void SetMessageCallback(MessageCallback&& callback)
        {
            message_callback_ = std::move(callback);
        }

        void SetMessageCallback(const MessageCallback& callback)
        {
            message_callback_ = callback;
        }

        void SetThreadNums(int thread_nums)
        {
            threadpool_->SetThreadNums(thread_nums);
        }

        void HandleClose(const TcpConnectionPtr& ptr);
        void HandleCloseInLoop(const TcpConnectionPtr& ptr);
        void HandleNewConnection(int connfd);

    private:
        typedef std::unordered_map<int, TcpConnectionPtr> ConnectionMap;

        EventLoop* loop_;
        std::unique_ptr<EventLoopThreadPool> threadpool_;
        std::unique_ptr<Acceptor> acceptor_;

        ConnectionCallback connection_callback_;
        MessageCallback message_callback_;
        ConnectionMap connections_;
    };
}

#endif

